package com.zrkizzy.seckill.service.core.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zrkizzy.seckill.dto.LoginDTO;
import com.zrkizzy.seckill.entity.User;
import com.zrkizzy.seckill.enums.HttpStatusEnum;
import com.zrkizzy.seckill.exception.GlobalException;
import com.zrkizzy.seckill.mapper.UserMapper;
import com.zrkizzy.seckill.service.core.IUserService;
import com.zrkizzy.seckill.service.tool.IRedisService;
import com.zrkizzy.seckill.utils.Md5Util;
import com.zrkizzy.seckill.vo.common.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Optional;

import static com.zrkizzy.seckill.constant.RedisConst.USER_PREFIX;
import static com.zrkizzy.seckill.constant.TimeConst.ONE_HOUR;

/**
 * <p>
 *  用户服务实现类
 * </p>
 *
 * @author zhangrongkang
 * @since 2023-03-20
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
    @Autowired
    private IRedisService redisService;
    @Autowired
    private UserMapper userMapper;

    /**
     * 执行登录操作
     *
     * @param loginDTO 登录数据传输对象
     * @param request request请求
     * @param response response响应
     * @return 公共返回对象
     */
    @Override
    public Result doLogin(LoginDTO loginDTO, HttpServletRequest request, HttpServletResponse response) {
        // 获取到用户名和密码
        String mobile = loginDTO.getMobile();
        String password = loginDTO.getPassword();
        // 在数据库中查询用户对象
        User user = userMapper.selectById(mobile);
        if (null == user) {
            throw new GlobalException(HttpStatusEnum.LOGIN_ERROR);
        }
        // 判断是否重复登录
        if (redisService.hasKey(USER_PREFIX + user.getId())) {
            return Result.error(HttpStatusEnum.REPEAT_LOGIN_ERROR);
        }
        // 如果查询出的对象密码不一致
        if (!Md5Util.formPassToDbPass(password, user.getSlat()).equals(user.getPassword())) {
            throw new GlobalException(HttpStatusEnum.LOGIN_ERROR);
        }
        // 设置当前用户信息到Redis中，过期时间为一小时
        redisService.set(USER_PREFIX + user.getId(), user, ONE_HOUR);
        return Result.success(user.getId());
    }

    /**
     * 从Cookie中获取User对象
     *
     * @param ticket 存储的ticket
     * @return 用户对象
     */
    @Override
    public User getUserByCookie(String ticket, HttpServletRequest request, HttpServletResponse response) {
        // 如果当前传来的ticket为空则直接返回null
        if (Optional.ofNullable(ticket).isEmpty()) {
            return null;
        }
        // 从Redis中查询用户对象
        return redisService.get(USER_PREFIX + ticket, User.class);
    }
}
